package com.balarawool.continuations.virtualthread;

import java.util.concurrent.ConcurrentLinkedQueue;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.atomic.AtomicBoolean;

import static com.balarawool.continuations.ExecutorUtils.shutdownExecutor;

public class VirtualThreadScheduler {

    public static ScopedValue<VirtualThread> CURRENT_VIRTUAL_THREAD = ScopedValue.newInstance();

    private final ConcurrentLinkedQueue<VirtualThread> queue = new ConcurrentLinkedQueue<>();
    private final ExecutorService executor = Executors.newFixedThreadPool(10);
    private final AtomicBoolean running = new AtomicBoolean(true);

    public void start() {
        while (running.get()) {
            if (!queue.isEmpty()) {
                var vt = queue.remove();
                executor.submit(() -> ScopedValue.where(CURRENT_VIRTUAL_THREAD, vt)
                        .run(vt::run));
            }
        }
        shutdownExecutor(executor, 10, TimeUnit.SECONDS);
    }

    public void stop() {
        running.set(false);
    }

    public void schedule(VirtualThread virtualThread) {
        queue.add(virtualThread);
    }
}
